package org.sgx.gwtsjcl.client;

import org.sgx.gwtsjcl.embedded.SJCLEmbeddedResources;

import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.ScriptInjector;
import com.google.gwt.core.client.ScriptInjector.FromUrl;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ExternalTextResource;
import com.google.gwt.resources.client.ResourceCallback;
import com.google.gwt.resources.client.ResourceException;
import com.google.gwt.resources.client.TextResource;
import com.google.gwt.resources.client.ClientBundle.Source;
/**
 * GWT class that let you load and use the base methods of 
 * Stanford Javascript Crypto Library - http://crypto.stanford.edu/sjcl/. Usage: 
 * 
<pre>SJCLLoader.load(new Callback<Void, Exception>() {			
	@Override
	public void onSuccess(Void result) {
		//ready to work
		String password = "banana4", plainText="En algún lugar de la mancha"; 
		String encrypted = SJCL.encrypt(password, plainText); 
		String decrypted = SJCL.decrypt(password, encrypted); 
	}			
	@Override
	public void onFailure(Exception reason) {
		Window.alert("Couldn't load SJCL Library from http://crypto.stanford.edu/sjcl/"); 
	}
}); </pre> 
 * @author sg
 *
 */
public class SJCLLoader {
	private static final String DEFAULT_URL = "http://crypto.stanford.edu/sjcl/sjcl.js";
	/**
	 * loads the JavaScript of the library from given url
	 * @param url
	 * @param callback
	 */
	public static void load(String url, final Callback<Void, Exception> callback) {
		if(url==null)
			url=DEFAULT_URL;
		FromUrl injector = ScriptInjector.fromUrl(url);		
		injector.setCallback(callback).setWindow(ScriptInjector.TOP_WINDOW).inject(); 
	}
	
	
	public interface SJCLResources extends ClientBundle {

		SJCLResources res = GWT.create(SJCLResources.class);
		
		@Source("script/sjcl.js")
		ExternalTextResource sjcl();
	}

	/**
	 * loads the JavaScript of the library from script located as an ExternalTextResource (distributed with this library sources).  
	 * @param callback
	 */
	public static void load(final Callback<Void, Exception> callback) {
		try {
			SJCLResources.res.sjcl().getText(new ResourceCallback<TextResource>() {				
				@Override
				public void onSuccess(TextResource resource) {
					ScriptInjector.fromString(resource.getText())
						.setWindow(ScriptInjector.TOP_WINDOW)
						.inject(); 
					callback.onSuccess(null); 
				}				
				@Override
				public void onError(ResourceException e) {
					callback.onFailure(e); 
				}
			});
		} catch (ResourceException e) {
			callback.onFailure(e); 
		} 
	}
}
